﻿using AutoCommunication.Enums;
using AutoCommunication.Helper;
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;

namespace AutoCommunication.Base
{
    /// <summary>
    /// 设备接口
    /// </summary>
    public interface IDevice
    {

        #region 事件

        /// <summary>
        /// 报警触发事件
        /// </summary>
        public event Action<BaseVariable, AlarmEventArgs> AlarmEvent;
        /// <summary>
        /// 连接成功事件
        /// </summary>
        public event Action<IDevice> ConnectedEvent;
        /// <summary>
        /// 变量的值改变
        /// </summary>
        public event Action<BaseVariable> DataChangeEvent;
        /// <summary>
        /// 循环读取一次变量事件
        /// </summary>
        public event Action<BaseVariable> CycleReadEvent;
        /// <summary>
        /// 断开连接事件
        /// </summary>
        public event Action<IDevice> DisConnectEvent;

        #endregion 事件

        #region 属性

        public int BufferSize { get; set; }
        public bool Connected { get; set; }
        public TimeSpan CycleTime { get; set; }
        public string DevDescription { get; set; }
        public string DevName { get; set; }
        /// <summary>
        /// 全局唯一变量名：场地名+设备名
        /// </summary>
        public string FullName { get; set; } 
        public EndianFormat Format { get; set; }
        public bool IsActive { get; set; }
        public bool IsFirstConnect { get; set; }
        public bool IsRuning { get; set; }
        public int MaxErrorCountIsDisconnect { get; set; }
        public int MaxReadBits { get; set; }
        public int ReConnectWaitTime { get; set; }
        public int Timeout { get; set; }
        /// <summary>
        /// 设备通讯组
        /// </summary>
        public List<GroupBase>  Groups { get; set; }
        /// <summary>
        /// 这个设备对应的所有变量
        /// </summary>
        public List<Variable>   Variables { get; set; }
        /// <summary>
        /// 用于取消线程
        /// </summary>
        public CancellationTokenSource CancleToken { get; set; }
        #endregion 属性

        #region Public 方法

        /// <summary>
        /// 第一次初始化:确认设备参数是否符合要求,不会调用Connect方法;
        /// <para>推荐在保存时候可以调用此方法来判断参数时候正确设置</para>
        /// <para>内部调用CheckDeviceParameters</para>
        /// <para>InitParameters</para>
        /// <para>CheckOther</para>
        /// </summary>
        /// <returns></returns>
        Result Init1();
        /// <summary>
        /// 第二次初始化
        /// <para>将设备添加到系统</para>
        /// </summary>
        /// <returns></returns>
        Result Init2();
        /// <summary>
        /// 打开连接（如果已经是连接状态会先关闭再打开）
        /// 调用connect方法,会将autoopen设置为false,就不会自动断开了
        /// </summary>
        /// <returns></returns>
        Result Connect();
        /// <summary>
        /// 关闭连接.调用dispose方法
        /// </summary>
        /// <returns></returns>
        Result DisConnect();
        /// <summary>
        /// 安全启动自动这台设备:会验证参数设定是否正确
        /// </summary>
        /// <returns></returns>
        Result Start();

        /// <summary>
        /// 取消线程,并且调用close  dispose方法
        /// </summary>
        /// <returns></returns>
        Result Stop();
        /// <summary>
        /// 暂停读取，但是不会断开连接
        /// </summary>
        /// <returns></returns>
        Result Pause();




        /// <summary>
        /// 如果是布尔,用0和1表示;其他值,直接输入就好
        /// </summary>
        /// <param name="name"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        Task<Result> WriteAsync(string name, double value);

        /// <summary>
        /// 保存为Json格式的配置文件 : 会调用Auto里面的SaveJson方法
        /// </summary>
        /// <returns></returns>
        Result SaveJson(string path = "setting.json");

        #endregion Public 方法

    }
}